import ujson
import uos


# 默认表头个数，可按需修改
DEFAULT_HEADER_COUNT = 13  # 通道数量
PARAM_NUM = 2   #传感器参数数量 (逻辑换需要修改)
#JSON配置文件
CONFIG_PATH = "config.json"
config_file_before_root = "/luadb/config.json"  # 根目录文件
config_file_root = "/haas/"
config_path = "/haas/config.json"

config= {}
headers_cache = None
headers_dirty = True
is_init = False

def get_config():
    global config
    return config

def config_init():
    global config , is_init
    if CONFIG_PATH in uos.listdir(config_file_root):
        try:
            with open(config_path, 'r') as f:
                config = ujson.load(f)
        except Exception as e:
            is_init = False
            return False
        is_init = True
    else:
        uos.rename(config_file_before_root,config_path)
        try:
            with open(config_path, 'r') as f:
                config = ujson.load(f)
        except Exception as e:
            is_init = False
            return False
        is_init = True

def _generate_default_headers(count: int = DEFAULT_HEADER_COUNT):
    try:
        n = int(count)
        if n <= 0:
            return tuple()
        return tuple(str(i) for i in range(1, n + 1))
    except Exception:
        return tuple()
        
def read_interval_from_config():
    global config, is_init
    if is_init:
        interval = config.get('interval', 300)
    else:
        interval = 300
    return interval
            
def read_headers_from_config():
    global headers_cache, headers_dirty, config
    try:
        if headers_cache is not None and headers_dirty is False:
            return headers_cache

        sensors_obj = config.get('sensors', {})
        header_obj = sensors_obj.get('header', {})
        if not isinstance(header_obj, dict) or not header_obj:
            headers_cache = _generate_default_headers()
            headers_dirty = False
            return headers_cache

        # 分区键排序：数字优先，兼容 '1' 与 1
        def _sort_key(k):
            try:
                return (0, int(k))
            except Exception:
                return (1, str(k))

        # 参数键排序：按 param_后缀数字升序
        def _param_index(p):
            try:
                return int(str(p).split('_', 1)[1])
            except Exception:
                return 999999

        headers = []
        for _, section in sorted(header_obj.items(), key=lambda kv: _sort_key(kv[0])):
                if not isinstance(section, dict):
                    continue
                # 找出所有 param_* 键并排序
                param_keys = [k for k in section.keys() if str(k).startswith('param_')]
                param_keys.sort(key=_param_index)
                # 依次读取所有参数值
                for pk in param_keys:
                    v = section.get(pk)
                    if v is None:
                        continue
                    s = str(v).strip()
                    if s:
                        headers.append(s)

        if not headers:
            headers_cache = _generate_default_headers()
        else:
            headers_cache = tuple(headers)
        headers_dirty = False
        return headers_cache
    except Exception as e:
        print("read_headers_from_config fallback:",e)
        headers_cache = _generate_default_headers()    # 异常回退
        headers_dirty = False
        return headers_cache

       
def read_sensor_schema(sensor_type:str):   # 传感器配置读取 soil
    global config, is_init
    if is_init:
        sensor_schema = config.get('sensors', {}).get(sensor_type, {})
    else:
        sensor_schema = {}
    return sensor_schema

def write_interval_to_config(interval:int):
    global headers_cache, headers_dirty, is_init, config
    if not is_init:
        return False
    config['interval'] = interval
    try:
        with open(config_path, 'w') as f:
            ujson.dump(config, f)
    except Exception as e:
        print("Failed to write config:", e)
        return False
    return True

def write_headers_to_config(headers:dict):
    global headers_cache, headers_dirty, is_init, config
    if not is_init:
        print("write_headers_to_config: config not initialized")
        return False
    headers_dict = build_header_by_group_size(headers,group_size=PARAM_NUM)
    config['sensors']['header'] = headers_dict
    # 更新后使缓存失效，下一次读取将重建缓存
    headers_cache = None
    headers_dirty = True
    try:
        with open(config_path, 'w') as f:
            ujson.dump(config, f)
    except Exception as e:
        print("Failed to write config:", e)
        return False
    return True



def build_header_by_group_size(new_header, group_size=2, specials=('power supply(V)',)):
    """
    按固定组大小 group_size 将扁平字典 new_header -> 嵌套 header。
    - 不依赖值内容的解析，值保持原样（可为任意字符串，如 '13123'）。
    - 空字符串或仅空白的项被忽略。
    - specials 中的值（大小写不敏感匹配）作为单独条目追加，每条目仅包含 param_1。
    - 不使用 enumerate。
    """
  
    if group_size <= 0:
        raise ValueError("group_size must init")

    # 1) 排序与清洗
    items_sorted = sorted(((int(k), v) for k, v in new_header.items()), key=lambda kv: kv[0])
    specials_set = {str(s).strip().lower() for s in specials}

    # 过滤空值并拆分普通项/特殊项（值保持原样）
    values = [v.strip() for _, v in items_sorted if isinstance(v, str) and v.strip()]
    normals = [v for v in values if v.lower() not in specials_set]
    special_vals = [v for v in values if v.lower() in specials_set]

    # 2) 构建分组
    header = {}
    group_index = 1

    for i in range(0, len(normals), group_size):
        chunk = normals[i:i + group_size]
        param_dict = {'param_' + str(j + 1): chunk[j] for j in range(len(chunk))}
        header[str(group_index)] = param_dict
        group_index += 1

    # 3) 追加特殊项（每项单独一组，仅 param_1）
    for sv in special_vals:
        header[str(group_index)] = {'param_1': sv}
        group_index += 1

    return header
    